const { insert, find } = require("../model/usersModel")
const bcrypt = require("bcrypt")
const jwt = require('jsonwebtoken')
//注册接口
/**
 * 
 * @param {Object} req 客户端的请求对象
 * @param {Object} res 服务端响应对象
 * @param {Function} next 释放控制权给下一个中间件 
 */
const regist = async (req, res, next) => {
    //获取post请求携带的参数  使用req.body

    // console.log(req.body);
    let { username, password } = req.body;

    //判断用户名和密码是否传递

    if (!username) {
        res.send({ state: false, status: 4002, msg: "必须传递用户名" })
        return
    }
    if (!password) {
        res.send({ state: false, status: 4002, msg: "必须传递用户密码" })
        return
    }

    //1.首先要查询数据库中是否存在该用户
    let isUserExists = await find({ username });

    // console.log("----------", isUserExists);
    //判断isuserExists是不是一个数组类型,如果是说明数据库查询成功,如果不是说明数据库查找出错
    if (Array.isArray(isUserExists)) {
        //判断isUserExists是不是一个空数组,如果是,说明没有该用户,可以注册
        if (isUserExists.length === 0) {
            //对密码进行加密
            let saltRounds = 10;//杂凑的次数
            let hashPasswrod = bcrypt.hashSync(password, saltRounds);
            // console.log(hashPasswrod)
            //改写req.body.password 将原来的password明文变成hash值
            req.body.password = hashPasswrod;
            let registRes = await insert(req.body);
            // console.log("====", registRes);
            if (registRes) { //注册成功
                res.send({ state: true, status: 2001, msg: "注册成功" });
            } else {
                res.send({ state: false, status: 5001, msg: "注册出错" });
            }
        } else {
            //用户重复了
            res.send({ state: false, status: 3001, msg: "用户名已经存在" });
        }
    }


    //2.如果存在,那么就要提示用户名已经存在,不允许注册

    //3.如果不存在,那么就将信息保存在数据库中


}


//登入

const login = async (req, res) => {
    //思路
    //1.获取客户端传递的用户名和密码
    //通过req.body获取客户端传递的用户名和密码
    let { username, password } = req.body;
    // Object.keys 获取对象的key,返回一个数组
    //2.判断用户名和密码是否传递,这两个字段缺一不可
    if (!username) {
        res.send({ state: false, status: 4002, msg: "必须传递用户名" })
        return
    }
    if (!password) {
        res.send({ state: false, status: 4002, msg: "必须传递用户密码" })
        return
    }

    //3.登入就是一个查库的过程,如果能够从数据库中查找到,说明登入成功,查找不到,登入失败

    let result = await find({ username });

    //因为要进行密码的校验
    //->通过用户名查找到该数据
    //->取出该条数据的hash密码=>和用户传入的密码进行校验
    //->校验成功=>提示登入成功
    //->校验失败=>账号密码错误

    // console.log(result);

    //如果能够查询到,那么会返回一个数组,数组中的结果就是查询到的文档,登入成功
    //首先要判断它是不是一个数组,因为如果不是一个数组,说明查询数据库出问题了
    if (Array.isArray(result)) {
        if (result.length) {
            //进行密码的校验
            //数据库中加密后的密码,和用户当前登入的密码进行校验
            // console.log(result);
            // 取出数据库加密之后的密码
            let hashPassword = result[0].password;
            //通过bcrypt进行校验
            let verify = bcrypt.compareSync(password, hashPassword)
            // console.log(verify)
            if (verify) {
                //登入成功
                //通过jsonwebtoken生成一个token(令牌)应该在这里生成
                //可以把不敏感的信息放到payload中,这样做的目的就是降低客户端和服务端的交互次数
                console.log(result);

                let payload = {//荷载内容
                    username: result[0].username,
                    email: result[0].email,
                    nickname: result[0].nickname,
                    phone: result[0].phone
                }

                let secret = "MY_NAME_IS_XIANG";//随机的密文,相当于'加盐'

                let token = jwt.sign(payload, secret, {
                    expiresIn: 60 * 1 //这几个token的生效时间是1分钟
                })
                //可以把用户信息挂到session上面
                req.session.userInfo = payload;
                res.send({ state: true, status: 200, msg: "登入成功" ,token})
            } else {
                res.send({ state: false, status: 4001, msg: "用户密码错误" })
            }

        } else {
            //返回空数组 说明不存在这个用户
            res.send({ state: false, status: 2001, msg: "当前用户不存在" })
        }
    }

    //如果查询不到,返回一个数组,登入失败
}

module.exports = {
    regist,
    login
}
